package rpc.server;

import rpc.RpcApplication;
import rpc.message.RpcRequest;
import rpc.message.RpcResponse;
import rpc.registry.LocalRegistry;
import rpc.serializer.Serializer;
import rpc.serializer.JsonSerializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * HTTP 请求处理器
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {

    @Override
    public void handle(HttpServerRequest request) {
        // 指定序列化器
        final Serializer serializer = new JsonSerializer();
        // 记录日志
        System.out.println("Received request: " + request.method() + " " + request.uri());
        // 同步处理 HTTP 请求
        new Thread(() -> {
            Serializer finalSerializer = serializer;
            request.bodyHandler(body -> {
                byte[] bytes = body.getBytes();
                RpcRequest rpcRequest = null;
                try {
                    rpcRequest = finalSerializer.deserialize(bytes, RpcRequest.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 构造响应结果对象
                RpcResponse rpcResponse = new RpcResponse();
                // 如果请求为 null，直接返回
                if (rpcRequest == null) {
                    rpcResponse.setMessage("rpcRequest is null");
                    doResponse(request, rpcResponse, finalSerializer);
                    return;
                }
                try {
                    // 获取要调用的服务实现类，通过反射调用
                    Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                    Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                    Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                    // 封装返回结果
                    rpcResponse.setData(result);
                    rpcResponse.setDataType(method.getReturnType());
                    rpcResponse.setMessage("ok");
                } catch (Exception e) {
                    e.printStackTrace();
                    rpcResponse.setMessage(e.getMessage());
                    rpcResponse.setException(e);
                }
                // 响应
                doResponse(request, rpcResponse, finalSerializer);
            });
        }).start();
    }

    /**
     * 响应
     *
     * @param request
     * @param rpcResponse
     * @param serializer
     */
    void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type", "application/json");
        try {
            // 序列化
            byte[] serialized = serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialized));
        } catch (IOException e) {
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
